﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using XNADota.ContentPipeline.MDX;

namespace XNADota.MDX
{
    public class Model
    {
        public List<Sequence> Sequences;
        public List<MdxTexture> Textures;
        public List<Material> Materials;
        public List<Geoset> Geosets;
        public List<Bone> Bones;
        public List<Helper> Helpers;

        public bool Validate()
        {
            bool ret = true;
            for (int i = 0; i < Sequences.Count; i++)
                if (Sequences[i].SequenceID != i)
                {
                    ret = false;
                    throw new Exception("Sequence ID is not correct.");
                }

            for (int i = 0; i < Textures.Count; i++)
                if (Textures[i].TextureID != i)
                {
                    ret = false;
                    throw new Exception("Texture ID is not correct.");
                }

            for (int i = 0; i < Materials.Count; i++)
                if (Materials[i].MaterialID != i)
                {
                    ret = false;
                    throw new Exception("Material ID is not correct.");
                }

            for (int i = 0; i < Geosets.Count; i++)
                if (Geosets[i].GeosetID != i)
                {
                    ret = false;
                    throw new Exception("Geoset ID is not correct.");
                }

            for (int i = 0; i < Bones.Count; i++)
                if (Bones[i].NodeId != i)
                {
                    ret = false;
                    throw new Exception("Object ID is not correct.");
                }
            for (int i = 0; i < Helpers.Count;  i++)
                if (Helpers[i].NodeId != i + Bones.Count)
                {
                    ret = false;
                    throw new Exception("Helper Object ID is not correct.");
                }

            return ret;
        }
    }

    public class Sequence
    {
        public int SequenceID;
        public Extent Extent;
        public int IntervalStart;
        public int IntervalEnd;
        public float MoveSpeed;
        public float Rarity;
        public bool NonLooping;
        public string Name;
        public int SyncPoint;
    }

    public class MdxTexture
    {
        public int TextureID;
        public int ReplaceableId;
        public Texture Texture2D;
    }

    public class Material
    {
        public int MaterialID;
        public Layer[] Layers;
    }

    public class Layer
    {
        public EMdxMaterialLayerFilterMode FilterMode;
        public int TextureId;
    }

    public class Geoset
    {
        public int GeosetID;
        public int MaterialID;
        public int TriangleCount;
        public int VerticesCount;
        public VertexPositionNormalTexture[] Vertices;
        public int[] Indices;
        public int[] VertexGroupID;
        public List<int>[] GeosetGroups;
    }

    public class AnimatorNode
    {
        public Vector4 Value;
        public Vector4 InTangent;
        public Vector4 OutTangent;
        public float Time;
    }

    public class Animator
    {
        public AnimatorNode[] AnimatorNodes;
        public EMdxInterpolationType Type;
    }

    public class Extent
    {
        public Vector3 Min;
        public Vector3 Max;
        public float Radius;
    }

    public class Bone : Node
    {
        public int GeosetId;
    }

    public class Helper : Node
    {
    }

    public class Node
    {
        public string Name;
        public int NodeId;
        public int ParentNodeId;
        public Vector3 PivorPoint;
        public Animator Translation;
        public Animator Rotation;
        public Animator Scaling;
    }

    public class InvalidModelException : Exception
    {
        public InvalidModelException() : base() { }
        public InvalidModelException(string message) : base(message) { }
        public InvalidModelException(string message, Exception innerException) : base(message, innerException) { }
    }
}
